#*- coding: UTF-8 -*-
from Tkinter import *
from _Outils.Job import *
import random
from MiniJeux.PartieMiniJeu import *
import time
import math

try:
    from wPIL import Image, ImageTk, ImageOps
except ImportError:
    try:
        from PIL import Image, ImageTk, ImageOps
    except ImportError:
        import sys
        import tkMessageBox
        tkMessageBox.showwarning("Erreur", "S.V.P. Installez PIL pour jouer sur ce système d'exploitation")
        sys.exit()


"""
TO-DO:
    Background image shall expand.
    All players' score shall be displayed.
    Thou shall not explode.
    Thou shall have fun.
    Thy who hack shall be killed (IRL).
    Die.
    THIS SHALL BE THE FIRST REAL MINI-GAME IMPLEMENTED IN CVM-FROGGER3000!
"""

#http://effbot.org/tkinterbook/

class Modele(PartieMiniJeu):
    def __init__(self, taille, nbCible, temps, listeJoueurs = None):
        PartieMiniJeu.__init__(self, "FrogShooter", listeJoueurs)
        self.description = """Dans ce jeu, vous devez attraper des mouches:
 - Les mouches en or valent 3 points!
 - Les mouches argent valent 2 points!
 - Les autres mouches valent 1 point.
   Attention, les mouches que les autres attrapent disparaissent"""
        self.listeJoueurs=listeJoueurs
        self.point=0
        self.nbCible=nbCible
        self.cibles=[]
        self.taille = taille
        self.creerCible(self.nbCible,taille)
        self.temps = temps
        self.statut=False
        self.jobPartieTermine = Job(0.05, self.checkIfPartieTermine)
        self.jobBougerCibles = Job(0.05, self.bougerCible)
        #modifier dur�e partie ci bas et le mod du temps dans timerDebut
        #self.t.start()
        
    def reset(self, listeJoueurs):
        print 'reset frogshooter'
        self.__init__(self.taille, self.nbCible, self.temps, listeJoueurs)
    
    def play(self):
        self.debutPartie=time.time();
        self.finPartie=self.debutPartie + self.temps
        self.jobBougerCibles.start();
        self.jobPartieTermine.start();
        self.statut=True
        return 1

    #Lorsqu'appel�, cr�es les cibles dans un tableau
    def creerCible(self,cibles,tailleSurfaceJeu):
        for i in range(cibles):
            self.cibles.append(Cible(tailleSurfaceJeu))
            
            
    def bougerCible(self):
        #for i in range(self.nbCible):
        for i in self.cibles:
            if i.posX>self.taille[0]+1:
                i.posX=0
            elif i.posX<-self.cibles[0].diametre:
                i.posX=self.taille[0]
                
            if i.posY>self.taille[1]+1:
                i.posY=0
            elif i.posY<-self.cibles[0].diametre:
                i.posY=self.taille[1]
                
            i.posX+=i.depX
            i.posY+=i.depY

    #� l'aide de l'index de la cible qui a �t� cliqu�, renplace la cible par une autre
    def remplacerCible(self,indexCible):
        self.cibles[indexCible]=Cible(self.taille)
        
    #Augmente le nombre de point en fonction du nombre de point que l'usager a 
    #et en fonction du nombre de point que la cible vallait
    def updatePoint(self,nomJoueur,nbPointAcquis):
        self.joueurs[nomJoueur].score+=nbPointAcquis
        print self.joueurs[nomJoueur].score , self.joueurs[nomJoueur].nom
        return self.joueurs[nomJoueur].score

    def getTaille(self):
        return self.taille

    def getTemps(self):
        return self.temps

    def getCibles(self):
        return self.cibles
    
    def getStatut(self):
        return self.statut

    def getListeJoueurs(self):
        return self.joueurs

    def checkIfPartieTermine(self):
        if time.time()>=self.finPartie:
            self.jobBougerCibles.stop()
            self.jobPartieTermine.stop()
            self.statut = False
            self.termine = True

    #Fonction qui calcule le temps du mini jeu, self.temps est le temps courrant du jeu EN SECONDE
    def getTempsRestant(self):
        return (int)(math.ceil(self.finPartie-time.time()));
        
class Vue:
    def __init__(self, parentGUI, partie, width, height):
        root = Frame(parentGUI)
        self.tailleSurfaceJeu = (width, height)
        self.root = root
        self.cibleGraph=[]
        self.widthSurfaceJeu=width
        self.heightSurfaceJeu=height-50
        (pWidth, pHeight) = partie.getTaille()
        self.ratioWidth = float(self.widthSurfaceJeu)/float(pWidth)
        self.ratioHeight = float(self.heightSurfaceJeu)/float(pHeight)
        self.labelPoint = []
        #root.minsize(self.tailleSurfaceJeu, self.tailleSurfaceJeu+70)
        #tailleSurfaceJeu-->modifis la taille de la fen�tre et la taille de la surface de jeu
        
        #Cr�ation de la r�f�rence sur la classe Modele
        self.canvas = Canvas(root,width=self.widthSurfaceJeu, height=self.heightSurfaceJeu)
        #self.canvas.pack(side='top', fill='both', expand='yes')
        
        self.mouche1=Image.open("MiniJeux/FrogShooter/images/mouche1.png")
        self.mouche2=Image.open("MiniJeux/FrogShooter/images/mouche2.png")
        self.mouche3=Image.open("MiniJeux/FrogShooter/images/mouche3.png")

        self.mouche1=self.mouche1.convert("RGBA")
        self.mouche1 = self.mouche1.resize((int(self.mouche1.size[0]*self.ratioWidth), int(self.mouche1.size[1]*self.ratioHeight)), Image.ANTIALIAS)
        self.mouche1 = ImageTk.PhotoImage(self.mouche1)
        self.mouche2=self.mouche2.convert("RGBA")
        self.mouche2 = self.mouche2.resize((int(self.mouche2.size[0]*self.ratioWidth), int(self.mouche2.size[1]*self.ratioHeight)), Image.ANTIALIAS)
        self.mouche2 = ImageTk.PhotoImage(self.mouche2)
        self.mouche3=self.mouche3.convert("RGBA")
        self.mouche3 = self.mouche3.resize((int(self.mouche3.size[0]*self.ratioWidth), int(self.mouche3.size[1]*self.ratioHeight)), Image.ANTIALIAS)
        self.mouche3 = ImageTk.PhotoImage(self.mouche3)
        
        self.imageBG = Image.open('MiniJeux/FrogShooter/images/backGRD_Frog_Shooter.jpg')
        self.imageBG = self.imageBG.resize((self.widthSurfaceJeu,int(self.heightSurfaceJeu*1.1)), Image.ANTIALIAS)
        self.imageBG = ImageTk.PhotoImage(self.imageBG)
        self.canvas.create_image(self.widthSurfaceJeu/2, self.heightSurfaceJeu/2,image=self.imageBG)
        
        
        c = Frame(root, bg='gray95', padx=8, pady=8, width=width, height=50)
        
        self.canvas.pack(side=TOP, expand=NO, fill=NONE)

        
        Label(c,text="Nom du joueur").grid(sticky=N, column=0, row=0)
        Label(c,text="Point: ").grid(sticky=N, column=0, row=1)
        
        Label(c,text="Temps: ").grid(sticky=N, column=0, row=2)
        self.labelTemps=Label(c, text=15)
        self.labelTemps.grid(sticky=N, column=1, row=2)
        c.columnconfigure(0,minsize=220)
        self.c = c
        #faire un while pour cr�er le bon nombre de joueur � l'aide de la liste
        #while (i>self.Joueurs.length)
        
        
        #remplacer la colone par i

        #self.labelPoint.grid(sticky=N, column=1, row=0)
        c.pack(side=TOP, expand=1, fill=BOTH)
        
    def start(self):
        self.canvas.bind("<Button-1>", self.clicCible)
        
    def afficherJoueurScores(self):
        listeJoueurs=self.parent.getListeJoueurs()
        i=0
        for j in listeJoueurs.keys() :
            Label(self.c,text=listeJoueurs[j].nom).grid(sticky=N, column=i+1, row=0)
            l = Label(self.c, text=0)
            l.grid(sticky=N, column=i+1, row=1)
            self.labelPoint.append(l)
            i+=1
            self.c.columnconfigure(0,minsize=220)

        
    def redessineCibles(self):
        self.canvas.delete("cible")
        self.dessinerCible(self.parent.getListeCible())
        
    def tempsRedessineCibles(self):
        if self.parent.getStatutPartie()==True:
            self.root.after(50, self.redessineCibles)
            self.root.after(50, self.tempsRedessineCibles)
        
    def dessinerCible(self,cibles):
        for i in range(len(cibles)):
            if cibles[i].point==1:
                self.cibleGraph.append(self.canvas.create_image(cibles[i].posX*self.ratioWidth, cibles[i].posY*self.ratioHeight,
                                                           image=self.mouche1, tags=("cible",str(i))))
            elif cibles[i].point==2:
                self.cibleGraph.append(self.canvas.create_image(cibles[i].posX*self.ratioWidth, cibles[i].posY*self.ratioHeight,
                                                           image=self.mouche2, tags=("cible",str(i))))
            else:
                self.cibleGraph.append(self.canvas.create_image(cibles[i].posX*self.ratioWidth, cibles[i].posY*self.ratioHeight,
                                                           image=self.mouche3, tags=("cible",str(i))))
                
        
    def clicCible(self,event):
        tag=self.canvas.gettags(CURRENT)
        if "cible" in tag:
            self.parent.remplacerCible(int(tag[1]))
          
    def updatePointGraph(self, point, leJoueur):
        listeJoueurs=self.parent.getListeJoueurs()
        i=0
        for j in listeJoueurs.values():
            #if listeJoueurs[j].nom==leJoueur:
            self.labelPoint[i].config(text=str(j.score))
            i+=1

    def updateTemps(self):
        temps = self.parent.getTempsRestant()
        self.labelTemps.config(text=temps)
        if(temps > 0):
            self.root.after(100,self.updateTemps)
        

        

class Controleur:
    def __init__(self, modele, vue, nomJoueur):
        self.vue=vue
        self.vue.parent = self
        self.nomJoueur = nomJoueur
        self.modele = modele
        self.vue.afficherJoueurScores()
        self.vue.start()
        self.vue.tempsRedessineCibles()
        self.vue.updateTemps()

    def getTempsRestant(self):
        return self.modele.getTempsRestant()

    def updateTemps(self,temps):
        self.vue.updateTemps(temps)
         
        
    def remplacerCible(self, index):
        if self.modele.getStatut()==True:
            self.updatePoint(self.modele.getCibles()[index].point)
            self.modele.remplacerCible(index)
            self.vue.root.after(50, self.vue.redessineCibles) #self.vue.redessineCibles()
            
    def updatePoint(self,pointCible):
        point=self.modele.updatePoint(self.nomJoueur, pointCible)
        self.vue.updatePointGraph(point, self.nomJoueur)
    
    def getTailleSurfaceJeu(self):
        return self.vue.tailleSurfaceJeu
   
    def getStatutPartie(self):
        return self.modele.getStatut()
    
    def getListeCible(self):
        return self.modele.getCibles()
    
    def getListeJoueurs(self):
        return self.modele.getListeJoueurs()
        
class Cible():
    def __init__(self,tailleSurfaceJeu):
        #si on consid�re que la cible a un diametre de 25
        tabPointCible=[1,1,1,1,2,2,3]
        tabDepCible=[-1,1]
        self.depX=tabDepCible[random.randrange(0,2)]*3
        self.depY=tabDepCible[random.randrange(0,2)]*3
        self.diametre = 25
        self.posX = random.randrange(tailleSurfaceJeu[0]-self.diametre)
        self.posY = random.randrange(tailleSurfaceJeu[1]-self.diametre)
        self.rayon = self.diametre/2
        #self.vitesseDeplacement = random.randrange(40)
        self.point = tabPointCible[random.randrange(0,7)]
        #ou bien une cible qui disparait quand on clique dessus, envoy� par le r�seau
        #donc la vitesse devient inutile, et on g�n�re les position al�atoirement
  
if __name__ == '__main__':
    # Module de tests
    taille = 600
    nbCible = 20
    temps = 3
    modele = Modele(taille,nbCible,temps,None)
    controleur=Controleur(modele, 'Phil', taille)